home *** CD-ROM | disk | FTP | other *** search
/ Light ROM 1 / LIGHT-ROM 1 (Amiga Library Services)(1994).iso / ffdisks / d927.lha / Ftp / src / main.c < prev    next >
C/C++ Source or Header  |  1993-10-07  |  10KB  |  594 lines

  1. /*
  2.  * Copyright (c) 1985, 1989 Regents of the University of California.
  3.  * All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms are permitted
  6.  * provided that the above copyright notice and this paragraph are
  7.  * duplicated in all such forms and that any documentation,
  8.  * advertising materials, and other materials related to such
  9.  * distribution and use acknowledge that the software was developed
  10.  * by the University of California, Berkeley.  The name of the
  11.  * University may not be used to endorse or promote products derived
  12.  * from this software without specific prior written permission.
  13.  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
  14.  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  15.  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  16.  */
  17.  
  18. #ifndef lint
  19. char copyright[] =
  20. "@(#) Copyright (c) 1985, 1989 Regents of the University of California.\n\
  21.  All rights reserved.\n";
  22. #endif /* not lint */
  23.  
  24. #ifndef lint
  25. static char sccsid[] = "@(#)main.c    based on 5.13 (Berkeley) 3/14/89";
  26. #endif /* not lint */
  27.  
  28. /*
  29.  * FTP User Program -- Command Interface.
  30.  */
  31. #define FTPVARS
  32. #include "ftp_var.h"
  33. #include <sys/socket.h>
  34. #ifdef AMI_TCP
  35. #include <bsdsocket.h>
  36. #else
  37. #include <ss/socket.h>
  38. #endif
  39. #include <sys/ioctl.h>
  40. #include <sys/types.h>
  41.  
  42. #include <arpa/ftp.h>
  43.  
  44. #include <signal.h>
  45. #include <stdio.h>
  46. #include <errno.h>
  47. #include <ctype.h>
  48. #include <netdb.h>
  49. #ifndef AMI_TCP
  50. #include <pwd.h>
  51. #endif
  52. //#include <syslog.h>
  53.  
  54. #ifdef __SASC
  55. int Enable_Abort;
  56. #endif
  57.  
  58. #if defined(sun) && !defined(FD_SET)
  59. typedef int uid_t;
  60. #endif
  61.  
  62. sig_t    intr();
  63. sig_t    lostpeer();
  64. char    *getlogin();
  65. extern char *home;
  66.  
  67. struct Library *OpenLibrary();
  68. #ifdef AMI_TCP
  69. struct Library *SocketBase=0;
  70. #else
  71. struct Library *SockBase=0;
  72. #endif
  73.  
  74. FILE *log_file = 0;
  75.  
  76. shut_down()
  77. {
  78.     if (log_file) fclose(log_file);
  79.     log_file = 0;
  80. #ifdef AMI_TCP
  81.     if (SocketBase)
  82.         CloseLibrary(SocketBase);
  83.     SocketBase = 0;
  84. #else
  85.     if (SockBase)
  86.     {    cleanup_sockets();
  87.         CloseLibrary(SockBase);
  88.     }
  89.     SockBase = 0;
  90. #endif
  91. }
  92.  
  93. extern int Enable_Abort;
  94.  
  95. main(argc, argv)
  96.     char *argv[];
  97. {
  98.     register char *cp;
  99.     int top;
  100.     extern char *mygetenv();
  101.  
  102. #ifdef AMI_TCP
  103.     SocketBase = OpenLibrary("bsdsocket.library",0L);
  104.     SetErrnoPtr(&errno,sizeof(errno));
  105. #else
  106.     SockBase = OpenLibrary("inet:libs/socket.library",0L);
  107.     setup_sockets(5,&errno);
  108. #endif
  109.     atexit(shut_down);
  110.  
  111.     sp = getservbyname("ftp", "tcp");
  112.     if (sp == 0) {
  113.         fprintf(stderr, "ftp: ftp/tcp: unknown service\n");
  114.         exit(1);
  115.     }
  116.     doglob = 0;
  117.     interactive = 1;
  118.     hash = 0;
  119.     logname = 0;
  120.     autologin = 1;
  121. #ifdef FTP_LOG_USAGE
  122. #ifdef LOG_LOCAL3
  123.         openlog("ftp", LOG_PID, LOG_LOCAL3);
  124. #else
  125.         openlog("ftp", LOG_PID);
  126. #endif /* LOG_LOCAL2 */
  127. #endif /* FTP_LOG_USAGE */
  128.     argc--, argv++;
  129.     while (argc > 0 && **argv == '-') {
  130.         for (cp = *argv + 1; cp && *cp; cp++)
  131.             switch (*cp) {
  132.  
  133.             case 'd':
  134.                 options |= SO_DEBUG;
  135.                 debug++;
  136.                 break;
  137.             
  138.             case 'v':
  139.                 verbose++;
  140.                 break;
  141.  
  142.             case 't':
  143.                 trace++;
  144.                 break;
  145.  
  146.             case 'i':
  147.                 interactive = 0;
  148.                 break;
  149.  
  150.             case 'n':
  151.                 autologin = 0;
  152.                 break;
  153.  
  154.             case 'g':
  155.                 doglob = 0;
  156.                 break;
  157.             case 'L':
  158.                 logname = cp+1;
  159.                 cp = 0;
  160.                 break;
  161.             case 'H':
  162.                 hash = 1;
  163.                 break;
  164.             case 'D':
  165.                 dldir = cp+1;
  166.                 cp = 0;
  167.                 break;
  168.             case 'U':
  169.                 uldir = cp+1;
  170.                 cp = 0;
  171.                 break;
  172.             default:
  173.                 fprintf(stdout,
  174.                   "ftp: %c: unknown option\n", *cp);
  175.                 exit(1);
  176.             }
  177.         argc--, argv++;
  178.     }
  179.  
  180.     fromatty = isatty(fileno(stdin));
  181.     /*
  182.      * Set up defaults for FTP.
  183.      */
  184.     (void) strcpy(typename, "ascii"), type = TYPE_A;
  185.     (void) strcpy(formname, "non-print"), form = FORM_N;
  186.     (void) strcpy(modename, "stream"), mode = MODE_S;
  187.     (void) strcpy(structname, "file"), stru = STRU_F;
  188.     (void) strcpy(bytename, "8"), bytesize = 8;
  189.     if (fromatty)
  190.         verbose++;
  191.     cpend = 0;           /* no pending replies */
  192.     proxy = 0;    /* proxy not active */
  193.     crflag = 1;    /* strip c.r. on ascii gets */
  194.  
  195.     /*
  196.      * Set up the home directory in case we're globbing.
  197.      */
  198.  
  199.     if (uldir == 0 || dldir == 0)
  200.     {    char currentdir[MAXPATHLEN];
  201.         getcwd(currentdir,MAXPATHLEN);
  202.         if (uldir == 0) uldir = currentdir;
  203.         if (dldir == 0) dldir = currentdir;
  204.     }
  205.  
  206.     if (logname)
  207.         log_file = fopen(logname,"a");
  208.  
  209.     home = uldir;
  210.     if (argc > 0) {
  211.         if (setjmp(toplevel))
  212.             exit(0);
  213. #ifndef __SASC
  214.         (void) signal(SIGINT, intr);
  215.         (void) signal(SIGPIPE, lostpeer);
  216. #endif
  217.         setpeer(argc + 1, argv - 1);
  218.     }
  219.     else
  220.     {    printf("[FTP] ");
  221.         strcpy(line,"open");
  222.         makeargv();
  223.         if (setjmp(toplevel) == 0) {
  224. #ifndef __SASC
  225.             (void) signal(SIGINT, intr);
  226.             (void) signal(SIGPIPE, lostpeer);
  227. #endif
  228.             setpeer(margc,margv);
  229.         }
  230.     }
  231.     
  232.     top = setjmp(toplevel) == 0;
  233.     if (top) {
  234. #ifndef __SASC
  235.         (void) signal(SIGINT, intr);
  236.         (void) signal(SIGPIPE, lostpeer);
  237. #endif
  238.     }
  239.     for (;;) {
  240.         cmdscanner(top);
  241.         top = 1;
  242.     }
  243. }
  244.  
  245. sig_t
  246. intr()
  247. {
  248.  
  249.     longjmp(toplevel, 1);
  250. }
  251.  
  252. sig_t
  253. lostpeer()
  254. {
  255.     extern int cout;
  256.     extern int data;
  257.  
  258.     if (connected) {
  259.         if (cout >= 0) {
  260.             (void) shutdown(cout, 1+1);
  261.             (void) s_close(cout);
  262.             cout = -1;
  263.         }
  264.         if (data >= 0) {
  265.             (void) shutdown(data, 1+1);
  266.             (void) s_close(data);
  267.             data = -1;
  268.         }
  269.         connected = 0;
  270.     }
  271.     pswitch(1);
  272.     if (connected) {
  273.         if (cout >= 0) {
  274.             (void) shutdown(cout, 1+1);
  275.             (void) s_close(cout);
  276.             cout = -1;
  277.         }
  278.         connected = 0;
  279.     }
  280.     proxflag = 0;
  281.     pswitch(0);
  282. }
  283.  
  284. /*char *
  285. tail(filename)
  286.     char *filename;
  287. {
  288.     register char *s;
  289.     
  290.     while (*filename) {
  291.         s = rindex(filename, '/');
  292.         if (s == NULL)
  293.             break;
  294.         if (s[1])
  295.             return (s + 1);
  296.         *s = '\0';
  297.     }
  298.     return (filename);
  299. }
  300. */
  301. /*
  302.  * Command parser.
  303.  */
  304. cmdscanner(top)
  305.     int top;
  306. {
  307.     register struct cmd *c;
  308.     struct cmd *getcmd();
  309.     extern int help();
  310.  
  311.     if (!top)
  312.         (void) putchar('\n');
  313.     for (;;) {
  314.         if (fromatty) {
  315.             printf("ftp> ");
  316.             (void) fflush(stdout);
  317.         }
  318.         if (gets(line) == 0) {
  319.             if (feof(stdin) || ferror(stdin))
  320.                 quit();
  321.             break;
  322.         }
  323.         if (line[0] == 0)
  324.             break;
  325.         makeargv();
  326.         if (margc == 0) {
  327.             continue;
  328.         }
  329.         c = getcmd(margv[0]);
  330.         if (c == (struct cmd *)-1) {
  331.             printf("?Ambiguous command\n");
  332.             continue;
  333.         }
  334.         if (c == 0) {
  335.             printf("?Invalid command\n");
  336.             continue;
  337.         }
  338.         if (c->c_conn && !connected) {
  339.             printf ("Not connected.\n");
  340.             continue;
  341.         }
  342.         (*c->c_handler)(margc, margv);
  343.         if (bell && c->c_bell)
  344.             (void) putchar('\007');
  345.         if (c->c_handler != help)
  346.             break;
  347.     }
  348. #ifndef __SASC
  349.     (void) signal(SIGINT, intr);
  350.     (void) signal(SIGPIPE, lostpeer);
  351. #endif
  352. }
  353.  
  354. struct cmd *
  355. getcmd(name)
  356.     register char *name;
  357. {
  358.     extern struct cmd cmdtab[];
  359.     register char *p, *q;
  360.     register struct cmd *c, *found;
  361.     register int nmatches, longest;
  362.  
  363.     longest = 0;
  364.     nmatches = 0;
  365.     found = 0;
  366.     for (c = cmdtab; p = c->c_name; c++) {
  367.         for (q = name; *q == *p++; q++)
  368.             if (*q == 0)        /* exact match? */
  369.                 return (c);
  370.         if (!*q) {            /* the name was a prefix */
  371.             if (q - name > longest) {
  372.                 longest = q - name;
  373.                 nmatches = 1;
  374.                 found = c;
  375.             } else if (q - name == longest)
  376.                 nmatches++;
  377.         }
  378.     }
  379.     if (nmatches > 1)
  380.         return ((struct cmd *)-1);
  381.     return (found);
  382. }
  383.  
  384. /*
  385.  * Slice a string up into argc/argv.
  386.  */
  387.  
  388. int slrflag;
  389.  
  390. makeargv()
  391. {
  392.     char **argp;
  393.     char *slurpstring();
  394.  
  395.     margc = 0;
  396.     argp = margv;
  397.     stringbase = line;        /* scan from first of buffer */
  398.     argbase = argbuf;        /* store from first of buffer */
  399.     slrflag = 0;
  400.     while (*argp++ = slurpstring())
  401.         margc++;
  402. }
  403.  
  404. /*
  405.  * Parse string into argbuf;
  406.  * implemented with FSM to
  407.  * handle quoting and strings
  408.  */
  409. char *
  410. slurpstring()
  411. {
  412.     int got_one = 0;
  413.     register char *sb = stringbase;
  414.     register char *ap = argbase;
  415.     char *tmp = argbase;        /* will return this if token found */
  416.  
  417.     if (*sb == '!' || *sb == '$') {    /* recognize ! as a token for shell */
  418.         switch (slrflag) {    /* and $ as token for macro invoke */
  419.             case 0:
  420.                 slrflag++;
  421.                 stringbase++;
  422.                 return ((*sb == '!') ? "!" : "$");
  423.                 /* NOTREACHED */
  424.             case 1:
  425.                 slrflag++;
  426.                 altarg = stringbase;
  427.                 break;
  428.             default:
  429.                 break;
  430.         }
  431.     }
  432.  
  433. S0:
  434.     switch (*sb) {
  435.  
  436.     case '\0':
  437.         goto OUT;
  438.  
  439.     case ' ':
  440.     case '\t':
  441.         sb++; goto S0;
  442.  
  443.     default:
  444.         switch (slrflag) {
  445.             case 0:
  446.                 slrflag++;
  447.                 break;
  448.             case 1:
  449.                 slrflag++;
  450.                 altarg = sb;
  451.                 break;
  452.             default:
  453.                 break;
  454.         }
  455.         goto S1;
  456.     }
  457.  
  458. S1:
  459.     switch (*sb) {
  460.  
  461.     case ' ':
  462.     case '\t':
  463.     case '\0':
  464.         goto OUT;    /* end of token */
  465.  
  466.     case '\\':
  467.         sb++; goto S2;    /* slurp next character */
  468.  
  469.     case '"':
  470.         sb++; goto S3;    /* slurp quoted string */
  471.  
  472.     default:
  473.         *ap++ = *sb++;    /* add character to token */
  474.         got_one = 1;
  475.         goto S1;
  476.     }
  477.  
  478. S2:
  479.     switch (*sb) {
  480.  
  481.     case '\0':
  482.         goto OUT;
  483.  
  484.     default:
  485.         *ap++ = *sb++;
  486.         got_one = 1;
  487.         goto S1;
  488.     }
  489.  
  490. S3:
  491.     switch (*sb) {
  492.  
  493.     case '\0':
  494.         goto OUT;
  495.  
  496.     case '"':
  497.         sb++; goto S1;
  498.  
  499.     default:
  500.         *ap++ = *sb++;
  501.         got_one = 1;
  502.         goto S3;
  503.     }
  504.  
  505. OUT:
  506.     if (got_one)
  507.         *ap++ = '\0';
  508.     argbase = ap;            /* update storage pointer */
  509.     stringbase = sb;        /* update scan pointer */
  510.     if (got_one) {
  511.         return(tmp);
  512.     }
  513.     switch (slrflag) {
  514.         case 0:
  515.             slrflag++;
  516.             break;
  517.         case 1:
  518.             slrflag++;
  519.             altarg = (char *) 0;
  520.             break;
  521.         default:
  522.             break;
  523.     }
  524.     return((char *)0);
  525. }
  526.  
  527. #define HELPINDENT (sizeof ("directory"))
  528.  
  529. /*
  530.  * Help command.
  531.  * Call each command handler with argc == 0 and argv[0] == name.
  532.  */
  533. help(argc, argv)
  534.     int argc;
  535.     char *argv[];
  536. {
  537.     extern struct cmd cmdtab[];
  538.     register struct cmd *c;
  539.  
  540.     if (argc == 1) {
  541.         register int i, j, w, k;
  542.         int columns, width = 0, lines;
  543.         extern int NCMDS;
  544.  
  545.         printf("Commands may be abbreviated.  Commands are:\n\n");
  546.         for (c = cmdtab; c < &cmdtab[NCMDS]; c++) {
  547.             int len = strlen(c->c_name);
  548.  
  549.             if (len > width)
  550.                 width = len;
  551.         }
  552.         width = (width + 8) &~ 7;
  553.         columns = 80 / width;
  554.         if (columns == 0)
  555.             columns = 1;
  556.         lines = (NCMDS + columns - 1) / columns;
  557.         for (i = 0; i < lines; i++) {
  558.             for (j = 0; j < columns; j++) {
  559.                 c = cmdtab + j * lines + i;
  560.                 if (c->c_name && (!proxy || c->c_proxy)) {
  561.                     printf("%s", c->c_name);
  562.                 }
  563.                 else if (c->c_name) {
  564.                     for (k=0; k < strlen(c->c_name); k++) {
  565.                         (void) putchar(' ');
  566.                     }
  567.                 }
  568.                 if (c + lines >= &cmdtab[NCMDS]) {
  569.                     printf("\n");
  570.                     break;
  571.                 }
  572.                 w = strlen(c->c_name);
  573.                 while (w < width) {
  574.                     w = (w + 8) &~ 7;
  575.                     (void) putchar('\t');
  576.                 }
  577.             }
  578.         }
  579.         return;
  580.     }
  581.     while (--argc > 0) {
  582.         register char *arg;
  583.         arg = *++argv;
  584.         c = getcmd(arg);
  585.         if (c == (struct cmd *)-1)
  586.             printf("?Ambiguous help command %s\n", arg);
  587.         else if (c == (struct cmd *)0)
  588.             printf("?Invalid help command %s\n", arg);
  589.         else
  590.             printf("%-*s\t%s\n", HELPINDENT,
  591.                 c->c_name, c->c_help);
  592.     }
  593. }
  594.